﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Text;
using System.Windows.Forms;
using System.Globalization;
using System.Threading;

namespace MulticastTV
{
    public partial class Form1 : Form
    {
        CultureInfo culture = CultureInfo.CurrentCulture;
        
        void epg_Finished(object sender, EpgArgs ea)
        {
            Epg epgs = (Epg)sender;
            //we have data
            if (ea.Message == "epg_finished")
            {
                if (epgs.result.Referer == "epg_form")
                {
                    daily.Invoke(new delegateEpgupdate(daily.populateDatatable), epgs.result);
                }
                else
                    this.Invoke(new delegateEpgupdate(EpgPopulateGui), epgs.result);
            }

            // no data
            else if (ea.Message == "no_data" && epgs.result.Referer == "main")
            {
                this.Invoke(new delegateNoParams(clearPopUp));
            }
            else if (ea.Message == "no_data" && epgs.result.Referer == "epg_form")
            {
                daily.Invoke(new delegateNoParams(daily.HidePanels));
            }
        }
        
        /// <summary>
        /// Update listview and pop-up.
        /// ONLINE Epg data has only "hh:mm" information !!!!!!
        /// When epg data is available, gui can be updated in two ways.
        /// If epg was started on channel change, then listview and pop-up must be repopulated.
        /// If epg was started from listview and channel wasn't changed, only listview must be repolulated.
        /// </summary>
        /// <param name="er">Epg result class with formated list</param>
        public void EpgPopulateGui(epgResult er)
        {
            listView1.BeginUpdate();
            listView1.Items.Clear();

            int count = er.EpgData.Count;
            if (count > 0)
            {
                DateTime refDate=DateTime.MinValue;
                bool pm=false;
                if (!er.DatetimeFormat)
                {
                    string[] ard = (string[])(er.EpgData[count - 1]);
                    string rd = ard[0];
                    refDate = DateTime.ParseExact(rd, "yyyy-MM-dd HH:mm", null);
                }

                int i = 0;
                foreach (string[] sarr in er.EpgData)
                {
                    if (i == count - 1)
                    {
                        break;
                    }
                  
                    if (er.Referer == "main" || er.Referer == "main_listview")
                    {
                         ListViewItem item = new ListViewItem();
                        item.Text = sarr[0].Split()[0] + " " + sarr[1];
                        if (item.Text.Length > 255)
                            item.Text.Substring(0, 255);

                        DateTime itemtime = DateTime.MinValue;
                        if (!er.DatetimeFormat)
                        {
                            itemtime = new DateTime(refDate.Year, refDate.Month, refDate.Day, int.Parse(sarr[0].Substring(0, 2)), int.Parse(sarr[0].Substring(3, 2)), 0);
                            if (itemtime.Hour > 12)
                                pm = true;
                            if (pm && itemtime.Hour < 12)
                                itemtime = itemtime.AddDays(1);
                        }
                        else
                        {
                            itemtime = DateTime.ParseExact(sarr[0], "HH:mm yyyy-MM-dd", null);
                        }
                        //Used for "add to schedule".
                        object[] mdata = new object[] { itemtime, sarr[3], er.Ip, er.Name, sarr[1] };
                        item.ToolTipText = itemtime.ToString(culture) + " " + sarr[1] + " - " + sarr[2];
                        item.Tag = mdata;

                        //Add item to list
                        listView1.Items.Add(item);
                    }
                    i++;
                }
            }

            listView1.EndUpdate();
            TimerEpgListview.Stop();
            if (er.Referer == "main")
                highlightCurrentEpgItem(true,true);  
            else
                highlightCurrentEpgItem(true,false); 
            TimerEpgListview.Start();
        }

        /// <summary>
        /// Highlights current item in epg listview and popup.
        /// This function is also called periodically on every 20s with updatePopUp parameter false.
        /// </summary>
        private void highlightCurrentEpgItem(bool highlightListView, bool updatePopUp)
        {
            DateTime now = DateTime.Now;
            int index = -1;
            bool AllElapsed = true;
            foreach (ListViewItem it in listView1.Items)
            {
                index++;
                DateTime time = (DateTime)((object[])(it.Tag))[0];
                int diff = time.CompareTo(now);
                if (diff < 0)// time is earlier than now
                {
                    // check for correct fonts
                    if (it.ForeColor != Properties.Settings.Default.EPGTextColor && index > 0)
                    {
                        listView1.Items[index - 1].ForeColor = Properties.Settings.Default.EPGTextColor;
                        listView1.Items[index - 1].Font = Properties.Settings.Default.EPGFont;
                    }
                }
                else
                {
                    // start time is later than now
                    AllElapsed = false;
                    break;
                }
            }
            // Highlight listview
            if (index != -1 && highlightListView)
            {
                //select last one and clear cache
                if (AllElapsed)
                {
                    index++;
                    epg.clearCache((string)((object[])(listView1.Items[0].Tag))[3]);
                }

                if (!listView1.Items[Math.Max(0, index - 1)].ForeColor.Equals(Properties.Settings.Default.EPGHighTextColor))
                {
                    listView1.BeginUpdate();
                    // ensure only one at one time
                    listView1.Items[Math.Max(0, index - 2)].ForeColor = Properties.Settings.Default.EPGTextColor;
                    listView1.Items[Math.Max(0, index - 2)].Font = Properties.Settings.Default.EPGFont;

                    listView1.Items[Math.Max(0, index - 1)].ForeColor = Properties.Settings.Default.EPGHighTextColor;
                    listView1.Items[Math.Max(0, index - 1)].Font = Properties.Settings.Default.EPGHighFont;

                    listView1.Items[Math.Max(0, index - 1)].EnsureVisible();
                  
                    listView1.EndUpdate();
                }
            }
            
            // Populate popup menu with current items
            if (updatePopUp)
            {
                populatePopUp(index);
            }
       }

        /// <summary>
        /// Populate pop-up
        /// </summary>
        /// <param name="index">Index</param>
        private void populatePopUp(int index)
        {
            if (index - 1 < 0)
                index = 1;
            string itema, itemb;
            DateTime timea, timeb;
            bool autoshow = false;
            if (Properties.Settings.Default.EpgFs)
                autoshow = true;
            else
                autoshow = false;

            int count = listView1.Items.Count;
            if (count > 0)
            {
                itema = listView1.Items[index-1].Text;
                timea = (DateTime)((object[])listView1.Items[index-1].Tag)[0];

                if (index  >= count)
                {
                    itemb = "";
                    timeb = DateTime.Now;
                }
                else
                {
                    itemb = listView1.Items[index].Text;
                    timeb = (DateTime)((object[])listView1.Items[index].Tag)[0];
                }
                PopUpupdateText(itema, itemb, timea, timeb, autoshow);
                return;
            }
            else
                PopUpupdateText("", "", DateTime.MinValue, DateTime.MinValue, autoshow);
        }

        private void clearPopUp()
        {
            PopUpupdateText("", "", DateTime.MinValue, DateTime.MinValue, Properties.Settings.Default.EpgFs);
        }
    }

    public class EpgArgs : System.EventArgs
    {
        private string message;

        public EpgArgs(string m)
        {
            this.message = m;
        }

        public string Message
        {
            get { return message; }
        }
    } 
}
